#pragma once
#include <cstdint>
#include <fstream>
#include <vector>

#pragma pack(push,1) // 将结构体对齐设置为1字节对齐
struct TGAHeader {
    std::uint8_t id_length=0 ;
    std::uint8_t color_map_type=0;
    std::uint8_t data_type_code = 0;
    std::uint16_t colormaporigin = 0;
    std::uint16_t colormaplength = 0;
    std::uint8_t  colormapdepth = 0;
    std::uint16_t x_origin = 0;
    std::uint16_t y_origin = 0;
    std::uint16_t width = 0;
    std::uint16_t height = 0;
    std::uint8_t bits_per_pixel = 0; // 每像素位数
    std::uint8_t image_descriptor = 0;
};
#pragma pack(pop)  // 恢复默认对齐方式

struct TGAColor {
    std::uint8_t bgra[4] = {0, 0, 0, 0};
    std::uint8_t byte_spp = 4;
    std::uint8_t &operator[](const int i) { return bgra[i]; }
};

struct TGAImage {
    enum Format { GRAYSCALE = 1, RGB = 3, RGBA = 4 };

    TGAImage() = default;

    TGAImage(int w, int h, int bpp);

    bool read_tga_file(const std::string &filename);

    [[nodiscard]] bool write_tga_file(const std::string &filename, bool vflip = true, bool rle = true) const;

    void flip_horizontally();

    void flip_vertically();

    [[nodiscard]] TGAColor get(int x, int y) const;

    void set(int x, int y, const TGAColor &c);

    [[nodiscard]] int width() const;

    [[nodiscard]] int height() const;

private:
    bool load_rle_data(std::ifstream &in);

    bool unload_rle_data(std::ofstream &out) const;

    int w = 0;
    int h = 0;
    std::uint8_t bpp = 0;
    std::vector<std::uint8_t> data = {};
};
